home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Libraries / BlobMgr / Demo Folder / Heb.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-21  |  9.4 KB  |  401 lines  |  [TEXT/KAHL]

  1. /*
  2.  * Blob Manager Demonstration:  Hebrew Alephbet module
  3.  *
  4.  * 26 July 1986    Paul DuBois
  5.  *
  6.  * 28 Dec 93
  7.  * - Convert blobs from picture blobs to procedure blobs.
  8.  * This gives better donor dimming on monitors that can do grayscale
  9.  * and drawing turns out to be a lot faster, too.
  10.  * - Receptor dimming is no longer done by inverting the blob, since
  11.  * that was done by changing the dimming pattern and mode, which don't
  12.  * as yet apply to procedure blobs.  I just gray them per the default
  13.  * dimming.  (Note: the code to change the dimming pattern/mode is
  14.  * still here as a reminder of when it needs to be changed, should I
  15.  * figure out how to make it apply to procedure blobs.)
  16.  */
  17.  
  18. # include    "TransSkel.h"
  19.  
  20.  
  21. # include    "BlobMgr.h"
  22. # include    "BlobDemo.h"
  23.  
  24.  
  25. # define    nLetters    22    /* 22 letters in Hebrew alephbet */
  26. # define    sitmSize    16    /* sicn item is 16 x 16 */
  27. # define    rWidth        76    /* receptor blob width and height */
  28. # define    rHeight        22
  29. # define    rHGap        2    /* horizontal and vertical gaps */
  30. # define    rVGap        5    /* between receptor blobs */
  31. # define    dWidth        sitmSize    /* ditto for donors */
  32. # define    dHeight        sitmSize
  33. # define    dHGap        12
  34. # define    dVGap        4
  35.  
  36. # define    pauseAns    1    /* what kind of pause? */
  37. # define    pauseMatch    2
  38.  
  39. typedef short Sitm[sitmSize];
  40. typedef Sitm    Sicn[1];
  41. typedef Sicn **SicnHandle;
  42.  
  43. static WindowPtr        wind;
  44. static FontInfo            fontInfo;
  45. static BlobSetHandle    hebDonors;
  46. static BlobSetHandle    hebReceptors;
  47. static SicnHandle        letterSicn;
  48.  
  49. static ControlHandle    checkCtl;
  50. static ControlHandle    resumeCtl;
  51. static ControlHandle    resetCtl;
  52. static ControlHandle    shuffleCtl;
  53. static ControlHandle    ansCtl;
  54.  
  55. static Boolean            paused = false;
  56. static short            pauseType;
  57.  
  58.  
  59. /*
  60.  * Plot sicn item in given rectangle.
  61.  * This is exactly analogous to the ToolBox PlotIcon routine,
  62.  * except that the item number within the sicn must be specified.
  63.  */
  64.  
  65.  
  66. static void
  67. PlotSicn (Rect *r, SicnHandle s, short i)
  68. {
  69. GrafPtr    thePort;
  70. BitMap    bm;
  71. Sitm    tmpSitm;
  72.  
  73.     /* create a small bitmap */
  74.     HLock ((Handle) s);
  75.     BlockMove (&((**s)[i]), &tmpSitm, (long) sizeof (Sitm));
  76.     HUnlock ((Handle) s);
  77.     bm.baseAddr = (Ptr) &tmpSitm;
  78.     bm.rowBytes = 2;            /* items are 16 bits wide */
  79.     SetRect (&bm.bounds, 0, 0, sitmSize, sitmSize);
  80.     GetPort (&thePort);
  81.     CopyBits (&bm, &thePort->portBits, &bm.bounds, r, srcCopy, nil);
  82. }
  83.  
  84.  
  85. static void
  86. LightControls (void)
  87. {
  88. short    onIfPaused, offIfPaused;
  89.  
  90.     onIfPaused = (paused ? normalHilite : dimHilite);
  91.     offIfPaused = (paused ? dimHilite : normalHilite);
  92.     HiliteControl (checkCtl, offIfPaused);
  93.     HiliteControl (resetCtl, offIfPaused);
  94.     HiliteControl (ansCtl, offIfPaused);
  95.     HiliteControl (resumeCtl, onIfPaused);
  96. }
  97.  
  98.  
  99. /*
  100.  * Draw a donor blob (one of the Hebrew letters, the index of which
  101.  * is specified as the blob's reference constant).  Since these have
  102.  * an empty static region, partCode is always inDragBlob and can be
  103.  * ignored.
  104.  */
  105.  
  106. static pascal void
  107. DrawDonor (BlobHandle bDst, BlobHandle bSrc, short partCode)
  108. {
  109. Rect    r;
  110.  
  111.     r = BDragBox (bDst);        /* draw it in the destination blob */
  112.     PlotSicn (&r, letterSicn, GetBRefCon (bSrc));
  113. }
  114.  
  115.  
  116. /*
  117.  * Draw a receptor blob.  The reference constant low word is the index of
  118.  * the title string.  These are never glued to another blob, so bSrc and
  119.  * bDst are always the same.
  120.  */
  121.  
  122. static pascal void
  123. DrawReceptor (BlobHandle bDst, BlobHandle bSrc, short partCode)
  124. {
  125. Rect    r;
  126. Str255        str;
  127. short    h, v;
  128.  
  129.     if (partCode == inDragBlob)        /* draw drag region */
  130.     {
  131.         r = BDragBox (bDst);
  132.         EraseRect (&r);
  133.         FrameRect (&r);
  134.     }
  135.     else                                /* draw static region */
  136.     {
  137.         r = BStatBox (bDst);
  138.         GetIndString (str, nameStrNo, LoWord (GetBRefCon (bSrc)));
  139.         h = (r.left + r.right - StringWidth (str)) / 2;
  140.         v = r.bottom - fontInfo.descent;
  141.         MoveTo (h, v);
  142.         DrawString (str);
  143.     }
  144. }
  145.  
  146.  
  147. static void
  148. MoveBlobs (BlobSetHandle bSet, short n1, short n2,
  149.                     short x, short y, short xd)
  150. {
  151.     for ( ; n1 <= n2; ++n1)
  152.     {
  153.         MoveBlob (GetBlobHandle (bSet, n1), inFullBlob, x, y);
  154.         x += xd;
  155.     }
  156. }
  157.  
  158.  
  159. static void
  160. MakeBlobs (void)
  161. {
  162. short        i;
  163. short        h, v;
  164. Rect        tRect, sitmRect;
  165. BlobHandle    b1, b2;
  166. short        hMid;
  167. short        x, y, delta;
  168.  
  169.     hMid = wind->portRect.right / 2 - 4;
  170.     
  171.     letterSicn = (SicnHandle) GetResource ('SICN', letrSicnNo);
  172.     DetachResource ((Handle) letterSicn);
  173.     hebDonors = NewBlobSet ();
  174.     hebReceptors = NewBlobSet ();
  175.     for (i = 0; i < nLetters; ++i)
  176.     {
  177.         b1 = NewBlob (hebDonors, true, 1, false, (long) i);
  178.         b2 = NewBlob (hebReceptors, true, 0, true, (long) (i + 1));
  179.  
  180.         SetRect (&sitmRect, 0, 0, sitmSize, sitmSize);
  181.         SetProcRectBlob (b1, DrawDonor, &sitmRect, &sitmRect);
  182.  
  183.         OffsetRect (&sitmRect, rWidth-sitmSize, 5);
  184.         SetRect (&tRect, 0, 5, rWidth-sitmSize-1, rHeight);
  185.         SetProcRectBlob (b2, DrawReceptor, &sitmRect, &tRect);
  186.  
  187.         NewBlobMatch (b1, b2);    /* assign donor -> receptor mapping */
  188.     }
  189.  
  190.     /*
  191.      * now arrange the blobs on the board.
  192.      */
  193.     x = hMid - 5*(dWidth+dHGap) - dWidth/2;
  194.     delta = dWidth + dHGap;
  195.     y = 5;
  196.     MoveBlobs (hebDonors, 0, 10, x, y, delta);
  197.     y += dHeight + dVGap;
  198.     MoveBlobs (hebDonors, 11, 21, x, y, delta);
  199.  
  200.     x = hMid - 3*(rWidth+rHGap);
  201.     y += dHeight + dVGap + 5;
  202.     delta = rWidth + rHGap;
  203.     MoveBlobs (hebReceptors, 0, 5, x, y, delta);
  204.     y += rHeight + rVGap;
  205.     MoveBlobs (hebReceptors, 6, 11, x, y, delta);
  206.     y += rHeight + rVGap;
  207.     MoveBlobs (hebReceptors, 12, 17, x, y, delta);
  208.     x = hMid - 2*(rWidth+rHGap);
  209.     y += rHeight + rVGap;
  210.     MoveBlobs (hebReceptors, 18, 21, x, y, delta);
  211.  
  212.     ShuffleBlobSet (hebDonors);
  213. }
  214.  
  215.  
  216. /*
  217.  * Handle mouse click.  When Answer is clicked, stick the index of the
  218.  * current glob in the high word of the receptor reference constant so
  219.  * it can be restored when Resume is clicked.
  220.  */
  221.  
  222. static pascal void
  223. Mouse (Point pt, long t, short mods)
  224. {
  225. ControlHandle    ctl;
  226. BlobHandle        b, g;
  227. short            mode;
  228. Pattern            p;
  229. short            index;
  230. long            refCon;
  231.  
  232.     if (!paused)
  233.     {
  234.         BlobClick (pt, t, hebDonors, hebReceptors);
  235.         if (BlobSetQuiet (hebReceptors))    /* if all correct */
  236.         {                                    /* override normal */
  237.             paused = true;                    /* control display */
  238.             pauseType = pauseAns;
  239.             LightControls ();
  240.             HiliteControl (resumeCtl, dimHilite);
  241.             HiliteControl (resetCtl, normalHilite);
  242.             FreezeBlobSet (hebReceptors);
  243.         }
  244.     }
  245.     if (FindControl (pt, wind, &ctl))
  246.     {
  247.         if (TrackControl (ctl, pt, nil))
  248.         {
  249.             if (ctl == checkCtl)
  250.             {
  251.                 paused = true;
  252.                 pauseType = pauseMatch;
  253.                 GetBDimInfo (&p, &mode);    /* hilite by inverting */
  254.                 SetBDimInfo (black, patXor);
  255.                 BlobFeedback (hebReceptors, normalDraw, dimDraw);
  256.                 SetBDimInfo (p, mode);
  257.                 LightControls ();
  258.                 if (BlobSetQuiet (hebReceptors))    /* if all correct */
  259.                 {                                    /* override normal */
  260.                     HiliteControl (resumeCtl, dimHilite);    /* control display */
  261.                     HiliteControl (resetCtl, normalHilite);
  262.                 }
  263.             }
  264.             else if (ctl == ansCtl)
  265.             {
  266.                 paused = true;
  267.                 pauseType = pauseAns;
  268.                 LightControls ();
  269.                 for (b = FirstBlob (hebReceptors); b != nil; b = NextBlob (b))
  270.                 {
  271.                     if (BGlob (b) == (BlobHandle) nil)
  272.                         index = 0xffff;
  273.                     else
  274.                         index = GetBlobIndex (hebDonors, BGlob (b));
  275.                     refCon = LoWord (GetBRefCon (b)) | ((long) index << 16);
  276.                     SetBRefCon (b, refCon);        /* save current glob setting */
  277.                     g = FirstBMatch (b);        /* attach real answer */
  278.                     if (g != BGlob (b))
  279.                         ZGlueGlob (g, b);
  280.                 }
  281.             }
  282.             else if (ctl == resumeCtl)
  283.             {
  284.                 paused = false;
  285.                 LightControls ();
  286.                 if (pauseType == pauseMatch)
  287.                     ThawBlobSet (hebReceptors);
  288.                 else
  289.                 {
  290.                     /* restore previous attachments */
  291.                     for (b = FirstBlob (hebReceptors); b != nil; b = NextBlob (b))
  292.                     {
  293.                         index = HiWord (GetBRefCon (b));
  294.                         SetBRefCon (b, LoWord (GetBRefCon (b)));
  295.                         if (index == 0xffff)
  296.                             g = (BlobHandle) nil;
  297.                         else
  298.                             g = GetBlobHandle (hebDonors, index);
  299.                         if (g != BGlob (b))
  300.                         {
  301.                             ZUnglueGlob (b);
  302.                             GlueGlob (g, b);
  303.                         }
  304.                     }
  305.                 }
  306.             }
  307.             else if (ctl == resetCtl)
  308.             {
  309.                 paused = false;
  310.                 LightControls ();
  311.                 ThawBlobSet (hebReceptors);
  312.                 ZUnglueGlobSet (hebReceptors);        /* clear and redraw */
  313.             }
  314.             else if (ctl == shuffleCtl)
  315.             {
  316.                 ShuffleBlobSet (hebDonors);        /* shuffle letters */
  317.                 ValidRect (&wind->portRect);
  318.             }
  319.         }
  320.     }
  321. }
  322.  
  323.  
  324. static pascal void
  325. Update (Boolean resized)
  326. {
  327. short    mode;
  328. Pattern    p;
  329.  
  330.     DrawControls (wind);
  331.     DrawBlobSet (hebDonors);
  332.     GetBDimInfo (&p, &mode);
  333.     if (paused && pauseType == pauseMatch)
  334.         SetBDimInfo (black, patXor);
  335.     DrawBlobSet (hebReceptors);
  336.     SetBDimInfo (p, mode);
  337. }
  338.  
  339.  
  340. static pascal void
  341. Activate (Boolean active)
  342. {
  343.     if (active)
  344.     {
  345.         SetDragRects (wind);
  346.         SetBCPermissions (true, true, false, true, true);
  347.     }
  348. }
  349.  
  350.  
  351. static pascal void
  352. Clobber (void)
  353. {
  354.     DisposeHandle ((Handle) letterSicn);
  355.     DoWClobber ();
  356. }
  357.  
  358.  
  359. void
  360. HebInit (void)
  361. {
  362. Rect    r;
  363. short    i, j;
  364.  
  365.     SkelWindow (wind = GetDemoWind (hebWindRes),
  366.                 Mouse,            /* mouse clicks */
  367.                 nil,            /* key clicks */
  368.                 Update,            /* updates */
  369.                 Activate,        /* activate/deactivate events */
  370.                 nil,            /* close window */
  371.                 Clobber,        /* dispose of window */
  372.                 nil,            /* idle proc */
  373.                 false);            /* irrelevant, since no idle proc */
  374.  
  375.     GetFontInfo (&fontInfo);
  376.  
  377.     MakeBlobs ();
  378.     i = wind->portRect.bottom - 25;
  379.     j = wind->portRect.right/2 - 205;
  380.     SetRect (&r, j, i, j+70, i+20);
  381.     checkCtl =
  382.         NewControl (wind, &r, "\pCheck", true, 0, 0, 0, pushButProc, 0L);
  383.     OffsetRect (&r, 85, 0);
  384.     resumeCtl =
  385.         NewControl (wind, &r, "\pResume", true, 0, 0, 0, pushButProc, 0L);
  386.     OffsetRect (&r, 85, 0);
  387.     ansCtl =
  388.         NewControl (wind, &r, "\pAnswer", true, 0, 0, 0, pushButProc, 0L);
  389.     OffsetRect (&r, 85, 0);
  390.     resetCtl =
  391.         NewControl (wind, &r, "\pReset", true, 0, 0, 0, pushButProc, 0L);
  392.     OffsetRect (&r, 85, 0);
  393.     shuffleCtl =
  394.         NewControl (wind, &r, "\pShuffle", true, 0, 0, 0, pushButProc, 0L);
  395.  
  396.     LightControls ();
  397.  
  398.     MakeFrontWind (wind);
  399. }
  400.  
  401.